using System;

namespace RapidHDL
{
	/// <summary>
	/// Summary description for Xor.
	/// </summary>
	public class Xor : Component
	{
		public NodeVector InputNodes;
		public NodeVector OutputNodes;

		NotGate oNotGate;
		AndGate oAnd1;
		AndGate oAnd2;
		OrGate oOr;
		
		public Xor(Component poParentComponent, string psName) : base (poParentComponent,psName)
		{
			InputNodes = this.CreateNodeVector("In",2);
			OutputNodes = this.CreateNodeVector("Out",1);

			oNotGate = new NotGate(this,"notGate",2);
			oAnd1 = new AndGate(this,"and1",2);
			oAnd2 = new AndGate(this,"and2",2);
			oOr = new OrGate(this,"orGate",2);
	
			//oNotGate.InputNodes = InputNodes;
			oNotGate.InputNodes.ConnectNodeVector(InputNodes);

			oAnd1.InputNodes[0] = InputNodes[0];
			oAnd1.InputNodes[1] = oNotGate.OutputNodes[1];

			oAnd2.InputNodes[0] = oNotGate.OutputNodes[0];
			oAnd2.InputNodes[1] = InputNodes[1];

			oOr.InputNodes[0] = oAnd1.OutputNodes[0];
			oOr.InputNodes[1] = oAnd2.OutputNodes[0];

			OutputNodes[0] = oOr.OutputNodes[0];
		}

		protected override Component TestBuildStructure(Component poTopComponent, string psTestName)
		{
			return new Xor(poTopComponent,"testXor");
		}

		protected override string TestComponent(Clock poClock, Component poTestComponent, string psTestName)
		{
			string sTestId;
			Xor oXor = (Xor)poTestComponent;

			sTestId = "01 = 1";
			oXor.InputNodes.NodeVectorAsString = "01";
			poClock.DoClock(1.0);
			if(oXor.OutputNodes.NodeVectorAsString != "1")
				return sTestId;

			sTestId = "10 = 1";
			oXor.InputNodes.NodeVectorAsString = "10";
			poClock.DoClock(1.0);
			if(oXor.OutputNodes.NodeVectorAsString != "1")
				return sTestId;

			sTestId = "00 = 0";
			oXor.InputNodes.NodeVectorAsString = "00";
			poClock.DoClock(1.0);
			if(oXor.OutputNodes.NodeVectorAsString != "0")
				return sTestId;

			sTestId = "11 = 0";
			oXor.InputNodes.NodeVectorAsString = "11";
			poClock.DoClock(1.0);
			if(oXor.OutputNodes.NodeVectorAsString != "0")
				return sTestId;

			sTestId = "1x = x";
			oXor.InputNodes.NodeVectorAsString = "1x";
			poClock.DoClock(1.0);
			if(oXor.OutputNodes.NodeVectorAsString != "x")
				return sTestId;

			return "";
		}

	}
}
